home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
archiver
/
lzhsourc.lzh
/
LZH.SRC
/
HUFST.S
< prev
next >
Wrap
Text File
|
1992-07-02
|
38KB
|
1,667 lines
;-----------------------------------------------------------------------
; This is a assembler-version of some parts of huf.c
;
; Coded in may 1990 by Thomas Quester
; Some of this code is reassembled C
;
; To get rid of scaling the array's, the values of dad, son, lson, rson
; hold the double value
;
;------------------------------------------------------------------------
; -----------------------------------------------------------------------
; Externals
; -----------------------------------------------------------------------
export Decode
export Encode
import EncodeEn
; export EncodePo
; export GetBit
; import GetByte
import InitTree
export PatchF
; export Putcode
export StartHuf
import _StdErrF
import _StdOutF
export blkcnt
export blocksize
; import code_buf
export codesize
export crc
export crc_getc
export crctbl
; import d_code
; import d_len
export dad
import error
import ferror
import fgetc
import ungetc
export flg_n
import fputc
; export freq
; export getbuf
; export getlen
import infile
; import last_mat
export lson
; import lson
; export match_length
; export match_position
import outfile
import outfname
; import p_code
; import p_len
import printcou
; export prnt
; export putbuf
; export putlen
import rewind
export rson
; export son
export text_buf
export textsize
export FileFits
import fwrite
; -----------------------------------------------------------------------
; Constants
; -----------------------------------------------------------------------
N equ 4096 ;Buffer size
F equ 60 ;lookahead buffer size
THRESHOLD equ 2
N_CHAR equ 256-THRESHOLD+F ;kinds of characters (0..N_CHAR-1)
T equ N_CHAR*2-1 ;size of table
R equ T-1 ;position of root
NIL equ N
FOLD equ 18
MAX_FREQ equ $8000
; -----------------------------------------------------------------------
; Putc (macro)
; -----------------------------------------------------------------------
outrec: ds.l 1 ; 0 Speicherzeiger
ds.l 1 ; 4 Länge
ds.l 1 ; 8 Basispointer
ds.l 1 ; 12 basislänge
; Simmuliere turbo-c's fwrite: D0 = 1
; a1 = zeiger auf FILE
; a0 = buffer
tcwrite: ds.w 1
my_fwrite: move.l d2,-(sp)
tst.b tcwrite
beq tc_fwrite
cmp.w #1,d0
bne.b tc_fwrite
move.l (a1),d2
cmp.l 8(a1),d2
bne.b tc_fwrite
move.w 16(a1),d2
movem.l d0-d1/a0-a2,-(sp)
move.l a0,-(sp)
move.l d1,-(sp)
move.w d2,-(sp)
move.w #$40,-(sp)
trap #1
lea 12(sp),sp
movem.l (sp)+,d0-d1/a0-a2
move.l (sp)+,d2
rts
tc_fwrite: move.l (sp)+,d2
bra fwrite
shipout: movem.l d0-a6,-(sp)
lea outrec(pc),a0
move.l (a0),d1 ; ptr
sub.l 8(a0),d1 ; - basis
beq ship2 ; Noch nie benutzt!
move.l 8(a0),a0 ; basis
move.l outfile(pc),d0
beq.b ship2
move.l d0,a1
moveq.l #1,d0
; btst #0,d1
; bcc.b shipodd ; schreibe ungerade byteanzahl
bsr my_fwrite
ship3: movea.l outfile(pc),A0
bsr ferror ; if (ferror(outfile))
tst.w D0
beq.b ship2
movea.l outfname,A0
moveq #$0E,D0
bsr error ; error(WTERR,outfname)
ship2: lea outrec(pc),a0
move.l 12(a0),4(a0)
move.l 8(a0),(a0)
movem.l (sp)+,d0-a6
rts
;shipodd: movem.l d0/d1/a0,-(sp)
; subq.l #1,d1
; bsr my_fwrite
; movem.l (sp)+,d0/d1/a0
; add.l d1,a0
; subq.l #1,a0
; moveq.l #1,d1
; bsr my_fwrite
; bra.b ship3
macro fputc reg
local putc1
lea outrec(pc),a0
move.l (a0),a1
move.b reg,(a1)+
move.l a1,(a0)
subq.l #1,4(a0)
bpl.b putc1
; Hier shipout
bsr shipout
putc1:
endm
OpenOut: movem.l d0-d3/a0-a2,-(sp)
move.l #-1,-(sp)
move.w #$48,-(sp); Malloc
trap #1
addq.l #6,sp
sub.l #20000,d0
move.l d0,d3
move.l d0,-(sp)
move.w #$48,-(sp)
trap #1
addq.l #6,sp
lea outrec(pc),a0
subq.l #7,d3
move.l d0,(a0)+
move.l d3,(a0)+
move.l d0,(a0)+
move.l d3,(a0)+
movem.l (sp)+,d0-d3/a0-a2
rts
CloseOut: bsr shipout
move.l 8+outrec(pc),-(sp)
move.w #$49,-(sp)
trap #1
addq.l #6,sp
rts
; -----------------------------------------------------------------------
; getc (fgetc)
; -----------------------------------------------------------------------
macro getc
local getc1
local getc2
local getceof
move.l (a0),a1
cmpa.l 4(a0),a1
bcc getc1
moveq.l #0,d0
move.b (a1)+,d0
move.l a1,(a0)
cmp.b d0,d0 ; set equal flag
bra.b getc2
getc1:
bsr fgetc
cmp.w #$ffff,d0
beq.b getceof
cmp.b d0,d0 ; set equal-flag
bra.b getc2
getceof: cmp.b #0,d0 ; set not equal
getc2:
endm
; Gets 2 bytes in d7
macro rgetc
local getc1
local getc2
move.l (a0),a1
cmpa.l 4(a0),a1
bcs.b getc1
movem.l d1-d2/a0-a2,-(sp)
bsr fgetc
movem.l (sp)+,d1-d2/a0-a2
bra.b getc2
getc1: moveq.l #0,d0
move.b (a1)+,d0
move.l a1,(a0)
getc2:
endm
; Gets 2 bytes in d7
macro getw
local Fits
local getwEnd
rgetc
move.w d0,d7
lsl.w #8,d7
rgetc
move.b d0,d7
getwEnd:
endm
; -----------------------------------------------------------------------
; crc_getc
; -----------------------------------------------------------------------
macro crcgetc
; int crc_getc(register FILE *stream)
; setcrc(ch)
move.w crc-lson(a2),D1
move.w d1,d2
eor.w D0,D1 ; c ^ crc
and.w #$ff,D1 ; & 0xff
add.w D1,D1 ; d2=cardinal (crc ^ c) & $ff
lea crctbl-lson(a2),A1
lsr.w #8,D2 ; d0=(crc >> 8)
move.w 0(A1,D1.w),D1 ; d1=crctbl[(crc ^ (ch)) & 0xff]
eor.w D2,D1
move.w D1,crc-lson(a2)
endm
; -----------------------------------------------------------------------
; putCode
; -----------------------------------------------------------------------
; void Putcode(register int l, register int c)
; d7 = putlen
; register a2 = putlen
; -2(a2)=putbuf
macro putcode
local PutCode1
local PutCode2
movem.w D3-D4,-(SP)
move.w D0,D4
move.w D1,D3
move.b d7,D2 ; d2=putlen
lsr.w D2,D1
or.w D1,d6 ; putbuf != c >> putlen
add.b D0,d7 ; putlen+=l
cmpi.b #8,d7 ; putlen
bcs PutCode2
move.w d6,D0 ; putbuf
lsr.w #8,D0
fputc d0 ; putc(putbuf,outfile)
; if ((putlen -= 8) >=8)
subq.b #8,d7 ; putlen
cmpi.b #8,d7 ; putlen
bcs.b PutCode1
fputc d6 ; putc(putbuf,outfile)
addq.l #2,codesize ; codesize+=2
subq.b #8,d7 ;putlen-=8
move.w D3,D0
move.b D4,D1
sub.b d7,D1 ; putlen
lsl.w D1,D0
move.w D0,d6 ; putbuf = c << (l-putlen)
bra.b PutCode2
PutCode1: move.w d6,D0 ; putbuf
lsl.w #8,D0
move.w D0,d6 ; putbuf <<=8
addq.l #1,codesize ; codesize++
PutCode2: movem.w (SP)+,D3-D4
endm
; -----------------------------------------------------------------------
; Reconstract a tree
; -----------------------------------------------------------------------
reconst: movem.l D0-A6,-(SP)
lea freq,A0
lea prnt-freq(a0),A1
lea son-freq(a0),A2
bra.b rcon_a
rcon: movem.l D0-A6,-(SP)
rcon_a: moveq #0,D0
moveq #0,D1
; Collect leaf nodes in the first half of the table
; and relace the freq by (freq+1)/2
rcon1: cmpi.w #2*T,0(A2,D1.w) ; if son[i] >= T
blt.b rcon2
moveq #1,D2
add.w 0(A0,D1.w),D2
lsr.w #1,D2
move.w D2,0(A0,D0.w) ; freq[j] = (freq[i]+1)/2
move.w 0(A2,D1.w),0(A2,D0.w) ; son[j]=son[i]
addq.w #2,D0 ; j++
rcon2: addq.w #2,D1 ; i++
cmp.w #2*T,D1 ; i < T
blo.b rcon1
; begin constructing tree by connecting sons
; for (i=0; j=N_CHAR; j < T; i+=2; j++) {
move.w #N_CHAR*2,D3
moveq #0,D4
rcon3: moveq #2,D0
add.w D4,D0 ; k=i+2
move.w 0(A0,D4.w),D6
add.w 0(A0,D0.w),D6 ; f=freq[i]+freq[k]
move.w D6,0(A0,D3.w) ; freq[j]=f
; for (k=j-1; f < freq[k]; k--);
moveq #-2,D5
add.w D3,D5
bra.b rcon5
rcon4: subq.w #2,D5
rcon5: cmp.w 0(A0,D5.w),D6
blo.b rcon4
addq.w #2,D5
move.w D3,D7
sub.w D5,D7 ; l=(j-k) * 2
lea 0(A0,D5.w),A3
bsr.b movemem ;nach oben schieben
move.w D6,0(A0,D5.w) ; freq[k]= f
lea 0(A2,D5.